﻿
using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Media3D;
using System.Windows.Threading;
using Microsoft.Devices;
using Microsoft.Phone.Controls;
using SLARToolKit;
using System.Windows.Controls.Primitives;
using System.ComponentModel;
using System.Threading;

namespace SLARToolKitWinPhoneSample
{
   public partial class MainPage
   {
      PhotoCamera photoCamera;
      DispatcherTimer dispatcherTimer;
      bool isInitialized;
      bool isDetecting;
      GrayBufferMarkerDetector arDetector;
      byte[] buffer;
      Matrix3D scale;
      Matrix3D viewport;
      Matrix3D centerAtOrigin;
      Matrix3DProjection matrix3DProjection;


      private Popup popup;
      private BackgroundWorker backroungWorker;
      // Constructor
      public MainPage()
      {
         InitializeComponent();
         ShowSplash();
      }

      //splashscreen
      private void ShowSplash()
      {
          this.popup = new Popup();
          this.popup.Child = new SplashScreenControl();
          this.popup.IsOpen = true;
          StartLoadingData();
      }

      private void StartLoadingData()
      {
          backroungWorker = new BackgroundWorker();
          backroungWorker.DoWork += new DoWorkEventHandler(backroungWorker_DoWork);
          backroungWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backroungWorker_RunWorkerCompleted);
          backroungWorker.RunWorkerAsync();
      }

      void backroungWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
      {
          this.Dispatcher.BeginInvoke(() =>
          {
              this.popup.IsOpen = false;

          }
          );
      }

      void backroungWorker_DoWork(object sender, DoWorkEventArgs e)
      {
          //here we can load data
          Thread.Sleep(5000);
      }
      protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
      {
         base.OnNavigatedTo(e);

        
         Dispatcher.BeginInvoke(() =>
                                {

                                   // Initialize the webcam
                                   photoCamera = new PhotoCamera();
                                   photoCamera.Initialized += PhotoCameraInitialized;
                         
                                   isInitialized = false;
                                   isDetecting = false;

                                   // Fill the Viewport Rectangle with the VideoBrush
                                   var vidBrush = new VideoBrush();

                                    //Rotate the rightview
                                   int LeftRotation = 90;
                                   vidBrush.RelativeTransform = new CompositeTransform() { CenterX = 0.5, CenterY = 0.5, Rotation = LeftRotation };
                                   vidBrush.SetSource(photoCamera);
                                   Viewport.Fill = vidBrush;
                                   Show.Visibility = Visibility.Collapsed;
                                   // Start timer
                                   dispatcherTimer = new DispatcherTimer {Interval = TimeSpan.FromMilliseconds(10)};
                                   dispatcherTimer.Tick += (sender, e1) => Detect();
                                   dispatcherTimer.Start();
                                });
      }

      protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
      {
         // Release resources
         if (dispatcherTimer != null)
         {
            dispatcherTimer.Stop();
            dispatcherTimer = null;
         }

         if (photoCamera != null)
         {
            Viewport.Fill = null;
            photoCamera.Initialized -= PhotoCameraInitialized;          
            photoCamera.Dispose();
         }

         base.OnNavigatedFrom(e);
      }

      private void Detect()
      {
         if (isDetecting || !isInitialized)
         {
            return;
         }

         isDetecting = true;
         var stopwatch = Stopwatch.StartNew();

         try
         {
            // Update buffer size
            var pixelWidth = (int)photoCamera.PreviewResolution.Width;
            var pixelHeight = (int)photoCamera.PreviewResolution.Height;
            if (buffer == null || buffer.Length != pixelWidth * pixelHeight)
            {
               buffer = new byte[pixelWidth * pixelHeight];

               // Create constant transformations instances
               // Center at origin of the 256x256 controls
               centerAtOrigin = Matrix3DFactory.CreateTranslation(-128, -128, 0);
               // Swap the y-axis and scale down by half
               scale = Matrix3DFactory.CreateScale(0.5, -0.5, 0.5);
               // Viewport transformation
               viewport = Matrix3DFactory.CreateViewportTransformation(pixelWidth, pixelHeight);
               matrix3DProjection = new Matrix3DProjection();
       
               Show.Projection = matrix3DProjection;
               //Img2.Projection = matrix3DProjection;
              // Img3.Projection = matrix3DProjection;
            }

            // Grab snapshot
            photoCamera.GetPreviewBufferY(buffer);

            // Detect
            var dr = arDetector.DetectAllMarkers(buffer, pixelWidth, pixelHeight);
          
            // Draw the detected squares
            //bitmap.Clear();
            //ViewportOverlay.Source = bitmap;

            // Calculate the projection matrix
            if (dr.HasResults)
            {
               
               // Calculate the complete transformation matrix based on the first detection result
               var world = centerAtOrigin * scale * dr[0].Transformation;

               // Calculate the final transformation matrix by using the camera projection matrix 
               var m = Matrix3DFactory.CreateViewportProjection(world, Matrix3D.Identity, arDetector.Projection, viewport);

               // Apply the final transformation matrix to the TextBox
               matrix3DProjection.ProjectionMatrix = m;
               Show.Visibility = Visibility.Visible;
             
            }
         }
         finally
         {
            isDetecting = false;
            stopwatch.Stop();
          
         }
      }

      void PhotoCameraInitialized(object sender, CameraOperationCompletedEventArgs e)
      {
         //  Initialize the Detector
         arDetector = new GrayBufferMarkerDetector();
         // Load the marker pattern. It has 16x16 segments and a width of 80 millimeters
         var marker = Marker.LoadFromResource("data/marker2.pat", 16, 16, 80);
         // The perspective projection has the near plane at 1 and the far plane at 4000
         arDetector.Initialize((int)photoCamera.PreviewResolution.Width, (int)photoCamera.PreviewResolution.Height, 1, 4000, marker);
        
         isInitialized = true;
      }

     

      


      private void Button_Click(object sender, RoutedEventArgs e)
      {
          NavigationService.Navigate(new Uri("/Page2.xaml", UriKind.Relative));
      }
      private void Button_Click2(object sender, RoutedEventArgs e)
      {
          NavigationService.Navigate(new Uri("/Page3.xaml", UriKind.Relative));
      }
      private void Button_Click3(object sender, RoutedEventArgs e)
      {
          NavigationService.Navigate(new Uri("/calculator.xaml", UriKind.Relative));
      }

      private void Button_Click4(object sender, RoutedEventArgs e)
      {
          NavigationService.Navigate(new Uri("/boxing_main.xaml", UriKind.Relative));
      }

      private void Button_Click5(object sender, RoutedEventArgs e)
      {
           NavigationService.Navigate(new Uri("/pageDessert.xaml", UriKind.Relative));
      }
      }
   }
